<?php

if ( empty($configure) || (empty($configure['log_dir'])) ) {
    $tiny_log_dir = '/tmp';
}
else {
    $tiny_log_dir = $configure[ 'log_dir' ];
}
echo "log_dir:$log_dir\n";

///////////////////////////////////////////////////////////////////////
//
// TinyLogger need $tiny_log_dir as log_root dir 

class	TinyLogger
{

    ///////////////////////////////////////////////////////////////////
    // constants declaration
    const	LEVEL_DEBUG = 80;
    const	LEVEL_INFO  = 50;
    const	LEVEL_WARN  = 40;
    const	LEVEL_ERROR = 20;

    ///////////////////////////////////////////////////////////////////
    // class variables declaration
    public	static	$level_name = array (
            self::LEVEL_DEBUG => 'DEBUG',
            self::LEVEL_INFO  => 'INFO',
            self::LEVEL_WARN  => 'WARN',
            self::LEVEL_ERROR => 'ERROR',
            );

    private	static	$instance = NULL;

    private static  $logger_instances = array ();

    ///////////////////////////////////////////////////////////////////
    //  instance variables declaration

    private	$log_dir = NULL;
    private	$log_today = NULL;
    private	$log_handles = array();
    private	$log_level = 0;

    private $log_config = NULL;


    ///////////////////////////////////////////////////////////////////
    //  methods 

    private	function	__construct()
    {
        $this->log_level = self::LEVEL_INFO;

        global	$tiny_log_dir;

        $this->log_dir = $tiny_log_dir;
        $this->log_today = date( 'Y-m-d' );
    }

    private	function	__clone()
    {
    }

    public	function	__destruct()
    {
        foreach ( $this->log_handles as $lvl => $fh ) {
            fclose( $fh );
        }
        $this->log_handles = array();
    }

    public	static	function	getLogger( $category = 'root' )
    {
        if ( isset( self::$logger_instances[ $category ] ) ) {
            return  self::$logger_instances[ $category ];

            if ( is_null(self::$instance) ) {
                $__class_name__ = __CLASS__;
                self::$instance = new $__class_name__();
            }
            self::$logger_instances[ $category ] = self::$instance;

            return	self::$instance;
        }

        public  function    loadConfig( $config = NULL )
        {
            if ( empty( $config ) ) {
                $config =<<<__CONFIG__
                    <?xml version="1.0" encoding="utf-8" ?>
                    <logger>
                    <appender name="FileAppender">
                    <param name="dir" value="/tmp/logger_php" />
                    <layout name="simple">
                    <param name="ConversionPattern" value="%d [%t] %p - %m%n" />
                    </layout>
                    </appender>
                    <category name="test">
                    <priority value="info" />
                    <appender-ref ref="FileAppender" />
                    </category>
                    <root>
                    <priority value="debug" />
                    <appender-ref ref="FileAppender" />
                    </root>
                    </logger>
                    __CONFIG__;
            }

            return  true;
        }

        public	function	setLogDir( $log_dir = '/tmp' ) 
        {
            if ( false == empty($log_dir) ) {
                $this->log_dir = $log_dir;
            }
        }

        public	function	setLogLevel( $level = 0 )
        {
            if ( $level > 0 ) {
                $this->log_level = $level;
            }
        }

        public	function	getLogLevel()
        {
            return	$this->log_level;
        }

        public	function	debug( $message, $file=NULL, $line=0 )
        {
            if ($this->log_level >= self::LEVEL_DEBUG ) {
                $this->__show( self::LEVEL_DEBUG, $message, $file, $line );
            }
        }

        public	function	info( $message, $file=NULL, $line=0 )
        {
            if ($this->log_level >= self::LEVEL_INFO ) {
                $this->__show( self::LEVEL_INFO, $message, $file, $line );
            }
        }

        public	function	warn( $message, $file=NULL, $line=0 )
        {
            if ($this->log_level >= self::LEVEL_WARN ) {
                $this->__show( self::LEVEL_WARN, $message, $file, $line );
            }
        }

        public	function	error( $message, $file=NULL, $line=0 )
        {
            if ($this->log_level >= self::LEVEL_ERROR ) {
                $this->__show( self::LEVEL_ERROR, $message, $file, $line );
            }
        }

        private	function	__show( $level, $message, $filename=NULL, $lineno=0 )
        {
            $today = date( 'Y-m-d' );
            if ( $today != $this->log_today ) {
                foreach ( $this->log_handles as $lvl => $fh ) {
                    fclose( $fh );
                }
                $this->log_handles = array();
                $this->log_today = $today;
            }

            if ( !isset( $this->log_handles[ $level ] ) ) {
                $fn = sprintf( "%s/%s.log.%s", $this->log_dir, strtolower(self::$level_name[$level]), $today );
                $fh = fopen( $fn, "a" );
                if (!$fh) {
                    error_log( __CLASS__ . " Fail to open log file $fn." );
                    return;
                }

                chmod($fn, 0666);
                $this->log_handles[ $level ] = $fh;
            }
            $fh = $this->log_handles[ $level ];

            $now = date( 'Y-m-d H:i:s' );

            if ( $filename ) {
                fprintf ( $fh, "%s %s:%d [%s] %s\n", $now, basename($filename), $lineno, self::$level_name[ $level ], $message );
            }
            else {
                fprintf ( $fh, "%s [%s] %s\n", $now, self::$level_name[ $level ], $message );
            }
        }
    }


    ///////////////////////////////////////////////////////////////////////
    // 

    function	getLogger()
    {
        return	TinyLogger::getLogger();
    }

    ?>
